#include "UIManager.h"
#include "../Entities/Book.h"
#include "Parser.h"
#include "Utils.h"
#include "../Managers/BookManager.h"
#include "../Entities/Hash/ExtensibleHash.h"
#include "../Entities/TreeB+/TreeBPlus.h"
#include "exception"
using namespace Managers;
using namespace Commons;
using namespace Tree;

UIManager::UIManager() {
}

int UIManager::doOperation(int numberOfParameters, char* parameters[]) {

	string operationSelected(parameters[1]);
//	string operationSelected("-q");
	int operationResult = 0;

	if (operationSelected == "-i" && numberOfParameters == 3) {
		string filePath(parameters[2]);
		operationResult = takeText(filePath);
		cout<<operationResult<<endl;
	} else if (operationSelected == "-e") {
		processPublishers();
	} else if (operationSelected == "-a") {
		processAuthors();
	} else if (operationSelected == "-t") {
		processTitles();
	} else if (operationSelected == "-p") {
		processWords();
	} else if (operationSelected == "-l") {
		showTakenFiles();
	} else if (operationSelected == "-o" && numberOfParameters == 3) {
		string fileID(parameters[2]);
		getFile(fileID);
	} else if (operationSelected == "-q") /*&& numberOfParameters == 3)*/ {
		string fileID(parameters[2]);
//		string fileID("0");
		deleteFile(fileID);
	} else if (operationSelected == "-v" && numberOfParameters > 3) {
		string tipeOfStructure(parameters[2]);
		string fileName(parameters[3]);
		printStructure(tipeOfStructure,fileName);
	}

	return operationResult;
}

int UIManager::takeText(string filePath) {
	int toReturn = 0;
	Parser* parser = new Parser();
	Book* bookToInsert = parser->parseBook(filePath);
	if (bookToInsert != NULL) {
		BookManager* bookManager = new BookManager();
		bookManager->addBook(bookToInsert);
		delete bookManager;
		toReturn = 1;
	} else
		toReturn = -1;

	delete bookToInsert;
	delete parser;
	return toReturn;
}

void UIManager::processPublishers() {

	BookManager* bookManager = new BookManager();
	vector<Record*>* recordsToInsert = bookManager->getBooksWithEntityNotProcessed(Title);

	TreeBPlus* tree = new TreeBPlus();
	for (unsigned int i = 0; i < recordsToInsert->size(); i++) {
		tree->addInTree(recordsToInsert->at(i));
	}
}

void UIManager::processAuthors() {

	BookManager* bookManager = new BookManager();
	vector<Record*>* recordsToInsert = bookManager->getBooksWithEntityNotProcessed(Author);

	TreeBPlus* tree = new TreeBPlus();
	for (unsigned int i = 0; i < recordsToInsert->size(); i++) {
		tree->addInTree(recordsToInsert->at(i));
	}
}

void UIManager::processTitles() {

	BookManager* bookManager = new BookManager();
	vector<Record*>* recordsToInsert = bookManager->getBooksWithEntityNotProcessed(Title);
	ExtensibleHash * hash = new ExtensibleHash("Title");
	for (unsigned int i = 0; i < recordsToInsert->size(); i++) {
		hash->insertRecord(recordsToInsert->at(i));
	}

	delete hash;
	delete bookManager;
}

void UIManager::processWords() {

	BookManager* bookManager = new BookManager();
	vector<Record*>* recordsToInsert = bookManager->getBooksWithEntityNotProcessed(Words);
	ExtensibleHash* hash = new ExtensibleHash("Words");
	for (unsigned int i = 0; i < recordsToInsert->size(); i++) {
		hash->insertRecord(recordsToInsert->at(i));
	}
	delete hash;
	delete bookManager;
}

void UIManager::showTakenFiles() {

	BookManager* bookManager = new BookManager();

	unsigned int offset = 0;

	cout << "Id     ";
	cout << "Title                    ";
	cout << "Author               ";
	cout << "Publisher                    ";
	cout << "Words Qty." << endl;

	while (bookManager->hasNextBook(offset)) {

		Book* book = new Book();

		book = bookManager->getNextBook(offset);
		cout<<"--------------------------------"<<endl;
		cout<<book->getStatus()<<endl;
		cout<<"--------------------------------"<<endl;
		if (book->getStatus() != -1) {

			cout << book->getEntityID();
			cout << "   " + book->getTitle() + "     ";
			cout << book->getAuthor() + "    ";
			cout << book->getPublisher() + "      ";
			cout << book->getWords()->size() << endl;
		}
		offset = offset + book->getBufferSize();
		delete book;
	}
	delete bookManager;
}

void UIManager::getFile(string fileID) {

	BookManager* bookManager = new BookManager();

	unsigned int offset = 0;

	while (bookManager->hasNextBook(offset)) {

		Book* book = new Book();

		book = bookManager->getNextBook(offset);

		if (book->getEntityID() == atoi(fileID.c_str())) {
			cout<< "ID: ";
			cout << book->getEntityID()<<endl;
			cout << "Title: " + book->getTitle()<<endl;
			cout << "Author: " + book->getAuthor()<<endl;
			cout << "Publisher: " + book->getPublisher()<<endl;
			break;
		}
		offset = offset + book->getBufferSize();
		delete book;
	}
	if(bookManager->getBooksManager()->isEndOfFile(offset)){
		cout<<"Book not found"<<endl;
	}
	delete bookManager;
}

void UIManager::deleteFile(string fileID) {
	BookManager* bookManager = new BookManager();
	unsigned int offset = 0;
	bool founded = false;

	while (bookManager->hasNextBook(offset)) {
		Book* book = new Book();
		book = bookManager->getNextBook(offset);
		book->setStatus(1);
		if (book->getEntityID() == atoi(fileID.c_str())) {
			int status = book->getStatus();
			bookManager->updateBook(book);
			int vectorProcess[4] = { 8, 4, 2, 1 };
			for (unsigned int i = 0; i < 4; i++) {
				if (status - vectorProcess[i] >= 0) {
					switch (vectorProcess[i]) {
					case (1): {
						cout << "entre al 1" << endl;
						ExtensibleHash* hash = new ExtensibleHash("Title");
						Record* record = new Record(book->getTitle(),
								book->getEntityID());
						hash->deleteRecord(record);
						delete record;
						delete hash;
						break;
					}
					case (2): {
						cout << "borra titulo" << endl;
						break;
					}
					case (4): {
						cout << "borra titulo" << endl;
						break;
					}
					case (8): {
						ExtensibleHash* hash = new ExtensibleHash("Words");
						vector<Record*>* toDelete = new vector<Record*> ;
						cout << book->getWords()->size() << endl;
						for (unsigned int j = 0; j < book->getWords()->size(); j++) {
							Record* toDel = Commons::Utils::getRecordIn(book->getWords()->at(j), toDelete);
							if (toDel == NULL) {
								cout << "entre en NUILL" << endl;
								toDel = new Record(book->getWords()->at(j),
										book->getEntityID());
								toDelete->push_back(toDel);
//								delete toDel;
							} else {
								cout << "NO entre en NUILL" << endl;
								toDel->insertOffset(book->getEntityID());
							}
							cout << j << endl;
						}
						for (unsigned int k = 0; k < toDelete->size(); k++) {
							hash->deleteRecord(toDelete->at(k));
						}
						delete hash;
						delete toDelete;

					}
					}
					status = status - vectorProcess[i];
				}
			}
			founded = true;
		}
		offset = offset + book->getBufferSize();
		delete book;
		if (founded) break;
	}

	if (bookManager->getBooksManager()->isEndOfFile(offset)) {
		cout << "Book not found" << endl;
	}
	delete bookManager;
}

void UIManager::printStructure(string type, string fileName) {
    if(type == "-t"){
    	string name = "Title";
		ExtensibleHash* hash = new ExtensibleHash(name);
		hash->exportToTxt(fileName);
    } else if (type == "-p"){
    	string name = "Words";
		ExtensibleHash* hash = new ExtensibleHash(name);
		hash->exportToTxt(fileName);
    }else if (type == "-e"){
    	/*
    	 * crea el árbol !!
    	 */
    }else if(type == "-a"){
    	/*
    	 * crea el árbol !!
    	 */
    }
}
 UIManager::~UIManager() {
}
